package com.hxs.learn.shiro.realm;

import com.hxs.learn.common.web.LoginInfo;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.hxs.learn.entity.core.SysUser;
import com.hxs.learn.service.core.SysRoleMenuPermissionService;
import com.hxs.learn.service.core.SysRoleService;
import com.hxs.learn.service.core.SysUserService;
import com.hxs.learn.shiro.jwt.JwtUtil;
import com.hxs.learn.shiro.jwt.TokenStatus;
import com.hxs.learn.shiro.token.JWTAuthenticationToken;

/**
 * @author huxinsheng
 */
@Component
public class MyJwtRealm extends BaseRealm {
    private final SysUserService               userService;
    private final SysRoleService               roleService;
    private final SysRoleMenuPermissionService roleMenuPermissionService;
    private final JwtUtil                      jwtUtil;

    @Autowired
    public MyJwtRealm(SysUserService userService, SysRoleService roleService,
                      SysRoleMenuPermissionService roleMenuPermissionService, JwtUtil jwtUtil) {
        this.userService               = userService;
        this.roleService               = roleService;
        this.roleMenuPermissionService = roleMenuPermissionService;
        this.jwtUtil                   = jwtUtil;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        JWTAuthenticationToken upToken   = (JWTAuthenticationToken) token;
        String                 loginName = jwtUtil.getUsernameFromToken(upToken.getToken());

        if (StringUtils.isEmpty(loginName)) {
            return null;
        }

        SysUser user = userService.findByLoginName(loginName);

        if ((user != null) && (jwtUtil.verifyToken(upToken.getToken()) == TokenStatus.VALID)) {
            return new SimpleAccount(user, upToken.getToken(), getName());
        }

        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        LoginInfo user = (LoginInfo) principals.getPrimaryPrincipal();

        return super.initPermission(roleService, roleMenuPermissionService, user.getUserId());
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTAuthenticationToken;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
